package v1

import (
	"cn.bupt.byy/monitor/config"
	"cn.bupt.byy/monitor/models"
	"github.com/gin-gonic/gin"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/util/rand"
	"log"
	"net/http"
	"strconv"
)

var (
	coreV1        = config.CoreV1()
	appV1         = config.AppsV1()
	nodeMetricses = config.NodeMetricses()
	namespace     = config.GlobalConfig.Byy.Namespace
)

// ListNodes
// @Summary 列出所有节点
// @Description 列出所有节点
// @Produce  json
// @Success 200 {object} []models.NodeInfo "ok"
// @Router /listNodes [get]
func ListNodes(c *gin.Context) {
	nodeList, err := coreV1.Nodes().List(c, metav1.ListOptions{})
	if err != nil {
		panic(err.Error())
	}
	infosMap := make(map[string]*models.NodeInfo, len(nodeList.Items))

	for _, node := range nodeList.Items {
		cpu := node.Status.Capacity["cpu"]
		memory := node.Status.Capacity["memory"]
		ni := &models.NodeInfo{
			Ip:                node.Status.Addresses[0].Address,
			Name:              node.Name,
			CreationTimestamp: node.CreationTimestamp.String(),
			CpuRate:           0,
			CpuCoreCount:      cpu.Value(),
			MemoryTotal:       memory.Value(),
			MemoryUsed:        0,
			DiskTotal:         0,
			DiskUsed:          0,
			Pods:              nil,
			Ready:             "True" == node.Status.Conditions[len(node.Status.Conditions)-1].Status,
		}
		infosMap[node.Name] = ni
	}

	// 填加监控信息
	metricsList, err := nodeMetricses.List(c, metav1.ListOptions{})
	if err != nil {
		panic(err.Error())
	}
	for _, metrics := range metricsList.Items {
		infosMap[metrics.Name].CpuRate = metrics.Usage.Cpu().AsApproximateFloat64()
		infosMap[metrics.Name].MemoryUsed = metrics.Usage.Memory().Value()
	}

	// 填加pod运行信息
	podList, err := coreV1.Pods(namespace).List(c, metav1.ListOptions{})
	if err != nil {
		panic(err.Error())
	}
	for _, pod := range podList.Items {
		if pod.ObjectMeta.DeletionTimestamp != nil {
			pod.Status.Phase = "Terminating"
		}
		infosMap[pod.Spec.NodeName].AddTask(&models.PodInfo{
			Name:     pod.Name,
			NodeName: pod.Spec.NodeName,
			NodeIp:   pod.Status.HostIP,
			Status:   string(pod.Status.Phase),
		})
	}

	res := make([]*models.NodeInfo, len(infosMap))

	i := 0
	for _, info := range infosMap {
		res[i] = info
		i++
	}

	if config.GlobalConfig.Byy.MockNode {
		ts := 11
		for j := i; j < ts; j++ {
			ni := &models.NodeInfo{
				Ip:                "10.108.169." + strconv.Itoa(j),
				Name:              "k8s-node-" + strconv.Itoa(j-1),
				CreationTimestamp: res[0].CreationTimestamp,
				CpuRate:           0.1 + float64(rand.Intn(3))/100,
				CpuCoreCount:      2,
				MemoryTotal:       res[0].MemoryTotal,
				MemoryUsed:        int64(200000000 + rand.Intn(300000000)),
				DiskTotal:         0,
				DiskUsed:          0,
				Pods:              nil,
				Ready:             j%3 != 0,
			}
			res = append(res, ni)
		}
	}

	c.JSON(http.StatusOK, res)
}

// ListAll
// @Summary 列出所有服务信息
// @Description 返回服务的service, deployment, pods 运行信息
// @Produce  json
// @Success 200 {object} []models.Byy "ok"
// @Router /listAll [get]
func ListAll(c *gin.Context) {
	serviceList, err := coreV1.Services(namespace).List(c, metav1.ListOptions{})
	if err != nil {
		log.Fatal(err)
	}
	deploymentList, err := appV1.Deployments(namespace).List(c, metav1.ListOptions{})
	if err != nil {
		log.Fatal(err)
	}

	podList, err := coreV1.Pods(namespace).List(c, metav1.ListOptions{})
	if err != nil {
		log.Fatal(err)
	}

	res := &models.Byy{
		SvcName:    "",
		DeployName: "",
		Pods:       nil,
	}

	if len(serviceList.Items) != 0 {
		res.SvcName = serviceList.Items[0].Name
	}
	if len(deploymentList.Items) != 0 {
		res.DeployName = deploymentList.Items[0].Name
	}

	if len(podList.Items) != 0 {
		res.Pods = make([]models.PodInfo, len(podList.Items))
		for i, p := range podList.Items {
			res.Pods[i] = models.PodInfo{
				Name:     p.Name,
				NodeName: p.Spec.NodeName,
				NodeIp:   p.Status.HostIP,
				Status:   string(p.Status.Phase),
			}
			if p.ObjectMeta.DeletionTimestamp != nil {
				res.Pods[i].Status = "Terminating"
			}
		}
	}

	c.JSON(http.StatusOK, res)
}
